package com.gitee.generator.universal.common;
  
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.ArrayList;
import java.io.Serializable;

/**
 * TreeNode
 * @since 2020-08-19 11:24
 * @author wsx
 */
@Slf4j
@Data
public class TreeNode implements Serializable {
    /** serialVersionUID */
    private static final long serialVersionUID = 1L;
    /** 父id */
    private int parentId;
    /** id */
    private int id;
    /** 节点名称 */
    private String nodeName;
    /** 节点数据 */
    private Object nodeData;
    /** 父节点 */
    private TreeNode parentNode;
    /** 子节点 */
    private List<TreeNode> childList;

    /** 构造器 */
    public TreeNode() {
        initChildList();
    }

    /** 构造器 */
    public TreeNode(Object nodeData) {
        this.nodeData = nodeData;
        initChildList();
    }
    /** 构造器 */
    public TreeNode(String nodeName, Object nodeData, TreeNode parentNode, List<TreeNode> childList) {
        this.nodeName = nodeName;
        this.nodeData = nodeData;
        this.parentNode = parentNode;
        this.childList = childList;
        parentNode.addChildNode(this);
    }
    /** 是否为叶子节点 */
    public boolean isLeaf() {
        return null==childList || childList.isEmpty();
    }
  
    /** 插入一个child节点到当前节点中 */
    public void addChildNode(TreeNode treeNode) {
        initChildList();
        childList.add(treeNode);
    }
    /** initChildList */
    public void initChildList() {
        if (childList == null){
            childList = new ArrayList<>();
        }
    }

    /** 是否为有效的树 */
    public boolean isValidTree() {
        return true;
    }
  
    /** 返回当前节点的父辈节点集合 */
    public List<TreeNode> getElders() {
        List<TreeNode> elderList = new ArrayList<>();
        TreeNode pn = this.getParentNode();
        if (pn != null) {
            elderList.add(pn);
            elderList.addAll(pn.getElders());
        }
        return elderList;
    }
  
    /** 返回当前节点的晚辈集合 */
    public List<TreeNode> getJuniors() {
        List<TreeNode> juniorList = new ArrayList<>();
        List<TreeNode> child = this.getChildList();
        if (child == null) {
            return juniorList;
        } else {
            for (TreeNode junior : child) {
                juniorList.add(junior);
                juniorList.addAll(junior.getJuniors());
            }
            return juniorList;
        }
    }
  
    /** 返回当前节点的孩子集合 */
    public List<TreeNode> getChildList() {
        return childList;
    }
  
    /** 删除节点和它下面的晚辈 */
    public void deleteNode() {
        TreeNode parent = this.getParentNode();
        if (parent != null) {
            parent.deleteChildNode(this.getId());
        }
    }
  
    /** 删除当前节点的某个子节点 */
    public void deleteChildNode(int childId) {
        List<TreeNode> childNodes = this.getChildList();
        childNodes.removeIf(child->child.getId() == childId);
    }
  
    /** 动态的插入一个新的节点到当前树中 */
    public boolean insertJuniorNode(TreeNode treeNode) {
        if (this.parentId == treeNode.getParentId()) {
            addChildNode(treeNode);
            return true;
        } else {
            for (TreeNode childNode : this.getChildList()) {
                boolean insertSuccess = childNode.insertJuniorNode(treeNode);
                if (insertSuccess) {
                    return true;
                }
            }
            return false;
        }
    }
  
    /** 找到一颗树中某个节点 */
    public TreeNode findTreeNodeById(int id) {
        if (this.id == id){
            return this;
        }
        if (childList == null || childList.isEmpty()) {
            return null;
        }
        for (TreeNode child : childList) {
            TreeNode resultNode = child.findTreeNodeById(id);
            if (resultNode != null) {
                return resultNode;
            }
        }
        return null;
    }
  
    /** 遍历一棵树，层次遍历 */
    public void traverse() {
        if (id < 0) {
            return;
        }
        print(this.id);
        if (childList == null || childList.isEmpty()){
            return;
        }
        for (TreeNode child : childList) {
            child.traverse();
        }
    }
    /** 打印树id */
    public void print(String content) {
        log.info(content);
    }
    /** 打印树id */
    public void print(int content) {
        this.print(String.valueOf(content));
    }

}

